/*******************************************************************************
 * @license
 * Copyright (c) 2012, 2019 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials are made 
 * available under the terms of the Eclipse Public License v1.0 
 * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution 
 * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html). 
 * 
 * Contributors: Anton McConville - IBM Corporation - initial API and implementation
 ******************************************************************************/
/*eslint-env browser, amd*/
/* This PluginEntry widget supplies the HTML and related interactivity to display
   detailed information about a single plugin. It is designed to work with the
   PluginList widget, but each plugin entry element should fit into any HTML list
   or table */

define(['i18n!orion/settings/nls/messages', 'orion/PageUtil', 'orion/objects', 'orion/webui/littlelib', 'orion/widgets/plugin/ServiceCarousel'],
		function(messages, PageUtil, objects, lib, ServiceCarousel) {

		/*	formatLocationAsPluginName - temporary function - 
		the current plugins don't provide useful enough, or 
		consistent meta-data to use for descriptions - so this 
		function derives what it can from naming patterns seen in
		existing commonly used plugin urls. */

	function formatLocationAsPluginName(location) {
	
		function wordToUpper(strSentence) {
	
			function convertToUpper() {
				return arguments[0].toUpperCase();
			}
	
			return strSentence.toLowerCase().replace(/\b[a-z]/g, convertToUpper);
		}
	
		var divides = location.split("/"); //$NON-NLS-0$
		var last = divides[divides.length - 1];
		last = last.split(".html")[0]; //$NON-NLS-0$
		last = last.replace(/([a-z])([A-Z])/, "$1 $2"); //$NON-NLS-0$
		last = wordToUpper(last);
		last = last.replace('plugin', ''); //$NON-NLS-0$
		last = last.replace('Plugin', ''); //$NON-NLS-0$
	
		if (last === '') {
			last = location;
		} else {
			last = last + ' - ' + location;  //$NON-NLS-0$
		}
		return last;
	}
	
	function createServiceDescriptions(plugin) {
		var serviceDescriptions = [];
		plugin.getServiceReferences().forEach(function(reference) {
			var serviceName = "";
			if (reference.getProperty("objectClass")){   //$NON-NLS-0$ 
				serviceName = reference.getProperty("objectClass").join(" ");   //$NON-NLS-0$   //$NON-NLS-1$ 
			}
			
			var serviceDescription = {
				service: serviceName,
				items: []
			};
	
			reference.getPropertyKeys().forEach(function(name) {
				var item = {
					item: name,
					value: reference.getProperty(name)
				};
				serviceDescription.items.push(item);
			});
			serviceDescriptions.push(serviceDescription);
		});
		return serviceDescriptions;
	}

	function PluginEntry(options, parentNode) {
		objects.mixin(this, options);
		this.node = parentNode || document.createElement("div"); //$NON-NLS-0$
	}
	objects.mixin(PluginEntry.prototype, {
		iconSource: "", //$NON-NLS-0$
	
		templateString: '<div class="plugin-entry" style="overflow:hidden;">' + //$NON-NLS-0$
							'<div class="plugin-list-item">' + //$NON-NLS-0$
								'<div>' + //$NON-NLS-0$
									'<div class="plugin-icon"></div>' + //$NON-NLS-0$
									'<div class="stretch">' + //$NON-NLS-0$
										'<span class="plugin-title"></span>' + //$NON-NLS-0$
										'<div class="plugin-status"></div>' + //$NON-NLS-0$
										'<div></div>' + //$NON-NLS-0$
										'<span class="plugin-description"></span>' + //$NON-NLS-0$
										'<div class="plugin-links" style="font-size:11px"></div>' + //$NON-NLS-0$ 
									'</div>' + //$NON-NLS-0$
									'<span class="plugin-commands"></span>' + //$NON-NLS-0$
								'</div>' + //$NON-NLS-0$
							'</div>'+ //$NON-NLS-0$
							'<div class="plugin-service-item" ></div>' + //$NON-NLS-0$ 
						'</div>', //$NON-NLS-0$
		serviceDescriptions: null,

		createElements: function() {
			lib.setSafeInnerHTML(this.node, this.templateString);
			this.pluginTitle = lib.$(".plugin-title", this.node);  //$NON-NLS-0$ 
			this.pluginStatus = lib.$(".plugin-status", this.node);  //$NON-NLS-0$ 
			this.pluginDescription = lib.$(".plugin-description", this.node);  //$NON-NLS-0$ 
			this.pluginLinks = lib.$(".plugin-links", this.node);  //$NON-NLS-0$ 
			this.commandSpan = lib.$(".plugin-commands", this.node);  //$NON-NLS-0$ 
			this.serviceContainer = lib.$(".plugin-service-item", this.node);  //$NON-NLS-0$ 
			this.postCreate();
		},
		destroy: function() {
			if (this.node) {
				this.node = this.pluginTitle = this.pluginDescription = this.pluginLinks = this.commandSpan = this.serviceContainer = null;
			}
		},
		show: function() {
			this.createElements();
		},
		addPluginLink: function(name, url)  {
			if (!PageUtil.validateURLScheme(url)) {
				console.log("Illegal "+ name +" URL: " + url);  //$NON-NLS-0$  //$NON-NLS-1$
				return;
			}
			var link = document.createElement("a"); //$NON-NLS-0$
			link.classList.add("plugin-link"); //$NON-NLS-0$
			link.href = url;
			link.title = name;
			link.textContent = name;
			this.pluginLinks.appendChild(link);
		},
		postCreate: function(){	
			var headers = this.plugin.getHeaders();
			var location = this.plugin.getLocation();
			var state = this.plugin.getState();
			if (this.plugin.getProblemLoading()){
				state = "broken"; //$NON-NLS-0$
			}
			
			if (PageUtil.validateURLScheme(location)){
				var link = document.createElement("a"); //$NON-NLS-0$
				link.href = location;
				link.title = headers.name || formatLocationAsPluginName(location);
				link.textContent = headers.name || formatLocationAsPluginName(location);
				this.pluginTitle.appendChild(link);
			} else {
				this.pluginTitle.textContent = headers.name || formatLocationAsPluginName(location);
			}			
			
			if (state){
				switch (state){
					// Ignore active, starting and stopping states
					case "uninstalled":  //$NON-NLS-0$
						this.pluginStatus.textContent = messages['pluginStatusNotLoaded'];  // Not installed
						break;
					case "installed": //$NON-NLS-0$
						this.pluginStatus.textContent = messages['pluginStatusNotLoaded']; // Dependencies not satisfied
						break;
					case "resolved": //$NON-NLS-0$
						this.pluginStatus.textContent = messages['pluginStatusNotRunning']; // User disabled
						break;
					case "broken": //$NON-NLS-0$
						var icon = document.createElement("span"); //$NON-NLS-0$
						icon.className = "core-sprite-error modelDecorationSprite"; //$NON-NLS-0$
						var content = document.createElement("span"); //$NON-NLS-0$
						content.textContent = messages['pluginStatusBroken']; // Problem during update/starting
						this.pluginStatus.appendChild(icon);
						this.pluginStatus.appendChild(content);
						break;
				}
			}
			
			this.pluginDescription.textContent = headers.description || messages['OrionPlugin'];

			// Additional Links
			if (headers.website) {
				this.addPluginLink(messages["Website"], headers.website);
			}
			if (headers.license) {
				this.addPluginLink(messages["License"], headers.license);
			}
			if (headers.login) {
				this.addPluginLink(messages["Login"], headers.login);
			}
			
			this.commandSpan.id = location;
			this.commandService.renderCommands("pluginCommand", this.commandSpan, location, this, "tool"); //$NON-NLS-1$ //$NON-NLS-0$
			this.serviceDescriptions = createServiceDescriptions(this.plugin);				
			this.carousel = new ServiceCarousel({serviceData:this.serviceDescriptions}, this.serviceContainer );
			this.carousel.show();
		}
	});
	return PluginEntry;
});